﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using T.FAS.Runtime.Metadata.Entity;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.DataModel.Dao
{
    /// <summary>
    /// 实体类编辑工具
    /// </summary>
    public class EntityTools
    {
        /*元数据部分*/
        public const string ID = "ID";
        public const string Code = "Code";
        public const string Name = "Name";
        /*系统字段部分*/
        public const string Creator = "Creator";
        public const string CreateTime = "CreateTime";
        public const string LastModifier = "LastModifier";
        public const string LastModifyTime = "LastModifyTime";
        public const string TenantID = "TenantID";
        public const string ProjectBranchID = "ProjectBranchID";

        private static Dictionary<string, Func<IMetaDataContent, object>> s_systemFieldFuncDict = new Dictionary<string, Func<IMetaDataContent, object>>
        {
            {Creator, content => content.Creator },
            {CreateTime, content => content.CreateTime},
            {LastModifier, content => content.LastModifier },
            {LastModifyTime, content => content.LastModifyTime },
        };

        private static Dictionary<string, Func<IMetaDataContent, object>> s_metadataFieldFuncDict = new Dictionary<string, Func<IMetaDataContent, object>>
        {
            {ID, content => content.MetaDataID },
            {Code, content => content.MetaDataCode },
            {Name, content => content.MetaDataName },
            {TenantID, content => {
                dynamic tmp = content;
                string tenantID = tmp.TenantID;
                if (string.IsNullOrEmpty(tenantID))
                    return content.MetaData?.TenantId;
                else
                    return tenantID;
            }},
        };

        /// <summary>
        /// 新增时填充系统字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public static void FillSystemFiledForAdd<T>(T obj, IMetaDataContent content)
        {
            try
            {
                Type t = typeof(T);
                var props = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).ToList();
                foreach (var systemField in s_systemFieldFuncDict.Keys)
                {
                    var prop = props.Find(p => string.Equals(p.Name, systemField));
                    if (prop == null)
                        continue;
                    prop.SetValue(obj, s_systemFieldFuncDict[systemField](content));
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.Tool.Error, "新增时填充系统字段失败", e);
            }
        }

        /// <summary>
        /// 编辑时填充系统字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public static void FillSystemFiledForUpdate<T>(T obj, IMetaDataContent content)
        {
            try
            {
                Type t = typeof(T);
                var props = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).ToList();
                props.Find(p => string.Equals(p.Name, LastModifier)).SetValue(obj, s_systemFieldFuncDict[LastModifier](content));
                props.Find(p => string.Equals(p.Name, LastModifyTime)).SetValue(obj, s_systemFieldFuncDict[LastModifyTime](content));
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.Tool.Error, "自动填充系统字段失败", e);
            }
        }

        /// <summary>
        /// 新增时填充系统字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public static void FillMainObjectFieldForAdd<T>(T obj, IMetaDataContent content)
        {
            Type t = typeof(T);
            var props = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).ToList();
            foreach (var prop in props)
            {
                if (s_systemFieldFuncDict.Keys.Contains(prop.Name))
                {
                    prop.SetValue(obj, s_systemFieldFuncDict[prop.Name](content));
                }
                if (s_metadataFieldFuncDict.Keys.Contains(prop.Name))
                {
                    prop.SetValue(obj, s_metadataFieldFuncDict[prop.Name](content));
                }
            }
        }

        /// <summary>
        /// 获取默认的过滤条件字典
        /// 1.TenantID
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetDefaultFilterCondition(IMetaDataContent content)
        {
            return new Dictionary<string, string>
            {
                { TenantID, s_metadataFieldFuncDict[TenantID](content) as string },
            };
        }
    }

    /// <summary>
    /// 校验工具
    /// </summary>
    public class ValidateTools
    {
        /// <summary>
        /// 校验实体类实例公共属性字段是否相同
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="obj1">实体类1</param>
        /// <param name="obj2">实体类2</param>
        /// <returns></returns>
        public static bool Compare<T>(T obj1, T obj2)
        {
            Type t = typeof(T);
            var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance);
            var props = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var field in fields)
            {
                
            }
            return false;
        }
    }
}
